package de.hft_stuttgart.dsa.ctt.gui.view;

import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerRow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import de.hft_stuttgart.dsa.ctt.model.ProblemInstance;

/**
 * 
 * @author Matthias Huber - Matthew.Huber@web.de
 *
 */
public class TimeTablerView implements IView {

	/**
	 * The shell of the user interface.
	 */
	private Shell shell;

	/**
	 * The composite which holds all widgets of the view.
	 */
	private Composite composite;

	private ComboViewer problemInstanceComboViewer;

	private Label nameValueLabel;

	private Label numberOfCoursesValueLabel;

	private Label numberOfRoomsValueLabel;

	private Label numberOfDaysValueLabel;

	private Label periodsPerDayValueLabel;

	private Label numberOfCurriculaValueLabel;

	private Label numberOfConstraintsValueLabel;

	private Label violationPointsValueLabel;

	private TableViewer tableViewer;

	public TimeTablerView(Shell shell) {
		this.shell = shell;
	}

	/**
	 * @see IView#show()
	 */
	public void show() {
		composite = new Composite(shell, SWT.BORDER);
		composite.setSize(shell.getClientArea().width, shell.getClientArea().height);
		composite.setLayout(new GridLayout(1, true));

		createGeneratorComposite(composite);

		createViewerComposite(composite);

		composite.layout();
	}

	private void createGeneratorComposite(Composite parent) {
		Composite generatorComposite = new Composite(parent, SWT.BORDER);
		generatorComposite.setLayout(new GridLayout(5, true));
		generatorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));

		// row: problem instance
		Label problemInstanceLabel = new Label(generatorComposite, SWT.NONE);
		problemInstanceLabel.setText("Problem Instance :");
		problemInstanceLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		problemInstanceComboViewer = new ComboViewer(generatorComposite, SWT.BORDER | SWT.DROP_DOWN);
		problemInstanceComboViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		problemInstanceComboViewer.addPostSelectionChangedListener(new ISelectionChangedListener() {

			@Override
			public void selectionChanged(SelectionChangedEvent e) {
				int selectedIndex = problemInstanceComboViewer.getCombo().getSelectionIndex();
				if (-1 != selectedIndex) {
					ProblemInstance problemInstance = (ProblemInstance) problemInstanceComboViewer.getElementAt(selectedIndex);
					nameValueLabel.setText(problemInstance.getName());
					numberOfCoursesValueLabel.setText(String.valueOf(problemInstance.getNumberOfCourses()));
					numberOfRoomsValueLabel.setText(String.valueOf(problemInstance.getNumberOfRooms()));
					numberOfDaysValueLabel.setText(String.valueOf(problemInstance.getDays()));
					periodsPerDayValueLabel.setText(String.valueOf(problemInstance.getPeriodsPerDay()));
					numberOfCurriculaValueLabel.setText(String.valueOf(problemInstance.getNumberOfCurricula()));
					numberOfConstraintsValueLabel.setText(String.valueOf(problemInstance.getNumberOfConstraints()));

					createTableBoundaries(problemInstance);
				}
			}
		});

		// ONLY FOR TESTING
		ProblemInstance problemInstance = new ProblemInstance();
		problemInstance.setName("comp01");
		problemInstance.setNumberOfCourse(30);
		problemInstance.setNumberOfRooms(6);
		problemInstance.setDays(5);
		problemInstance.setPeriodsPerDay(6);
		problemInstance.setNumberOfCurricula(14);
		problemInstance.setNumberOfConstraints(53);
		problemInstanceComboViewer.add(problemInstance);

		Label emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: name
		Label nameLabel = new Label(generatorComposite, SWT.NONE);
		nameLabel.setText("Name :");
		nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		nameValueLabel = new Label(generatorComposite, SWT.RIGHT);
		nameValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: number of courses
		Label numberOfCoursesLabel = new Label(generatorComposite, SWT.NONE);
		numberOfCoursesLabel.setText("Number of courses :");
		numberOfCoursesLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		numberOfCoursesValueLabel = new Label(generatorComposite, SWT.RIGHT);
		numberOfCoursesValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: number of rooms
		Label numberOfRoomsLabel = new Label(generatorComposite, SWT.NONE);
		numberOfRoomsLabel.setText("Number of rooms :");
		numberOfRoomsLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		numberOfRoomsValueLabel = new Label(generatorComposite, SWT.RIGHT);
		numberOfRoomsValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: number of days
		Label numberOfDaysLabel = new Label(generatorComposite, SWT.NONE);
		numberOfDaysLabel.setText("Number of days :");
		numberOfDaysLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		numberOfDaysValueLabel = new Label(generatorComposite, SWT.RIGHT);
		numberOfDaysValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: periods per day
		Label periodsPerDayLabel = new Label(generatorComposite, SWT.NONE);
		periodsPerDayLabel.setText("Periods per day :");
		periodsPerDayLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		periodsPerDayValueLabel = new Label(generatorComposite, SWT.RIGHT);
		periodsPerDayValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: number of curricula
		Label numberOfCurriculaLabel = new Label(generatorComposite, SWT.NONE);
		numberOfCurriculaLabel.setText("Number of Curricula :");
		numberOfCurriculaLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		numberOfCurriculaValueLabel = new Label(generatorComposite, SWT.RIGHT);
		numberOfCurriculaValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: number of constraints
		Label numberOfConstraintsLabel = new Label(generatorComposite, SWT.NONE);
		numberOfConstraintsLabel.setText("Number of Constraints :");
		numberOfConstraintsLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		numberOfConstraintsValueLabel = new Label(generatorComposite, SWT.RIGHT);
		numberOfConstraintsValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// row: generate button
		new Label(generatorComposite, SWT.NONE).setVisible(false);

		Button generateSolutionButton = new Button(generatorComposite, SWT.PUSH);
		generateSolutionButton.setText("Generate new solution");
		generateSolutionButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// empty row
		emptyLabel = new Label(generatorComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 5, 1));

	}

	private void createViewerComposite(Composite parent) {
		Composite viewerComposite = new Composite(parent, SWT.BORDER);
		viewerComposite.setLayout(new GridLayout(5, true));
		viewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		// row: result
		Label resultLabel = new Label(viewerComposite, SWT.NONE);
		resultLabel.setText("Result :");
		resultLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		ComboViewer resultComboViewer = new ComboViewer(viewerComposite, SWT.BORDER | SWT.DROP_DOWN);
		resultComboViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));

		Label emptyLabel = new Label(viewerComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));

		// empty row
		emptyLabel = new Label(viewerComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 5, 1));

		// row: number of violation points
		Label violationPointsLabel = new Label(viewerComposite, SWT.NONE);
		violationPointsLabel.setText("Number of violation points :");
		violationPointsLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		violationPointsValueLabel = new Label(viewerComposite, SWT.RIGHT);
		violationPointsValueLabel.setText("X");
		violationPointsValueLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));

		emptyLabel = new Label(viewerComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));

		// empty row
		emptyLabel = new Label(viewerComposite, SWT.NONE);
		emptyLabel.setVisible(false);
		emptyLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 5, 1));

		// table
		tableViewer = new TableViewer(viewerComposite, SWT.HIDE_SELECTION);
		tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
		tableViewer.getTable().setHeaderVisible(true);
		tableViewer.getTable().setLinesVisible(true);
	}

	private void createTableBoundaries(ProblemInstance problemInstance) {
		int numberOfPeriods = problemInstance.getDays() * problemInstance.getPeriodsPerDay();
		int numberOfRooms = problemInstance.getNumberOfRooms();

		TableViewerColumn firstEmptyColumn = new TableViewerColumn(tableViewer, SWT.CENTER);
		firstEmptyColumn.getColumn().pack();
		
		for (int i = 0; i < numberOfPeriods; ++i) {
			TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, SWT.CENTER);
			tableViewerColumn.getColumn().setText("P " + (i + 1));
			tableViewerColumn.getColumn().pack();
		}
		
		// TODO MH: rework
		Table table = tableViewer.getTable();
		for (int i = 0; i < numberOfRooms; ++i) {
			TableItem tableItem = new TableItem(table, SWT.NONE);

			String[] rowContent = new String[numberOfRooms + 1];
			for (int j = 0; j <= numberOfRooms; ++j) {
				if (j > 0) {
					rowContent[j] = "";
				} else {
					rowContent[j] = "R " + i;
				}
			}
			tableItem.setText(rowContent);
		}
	}

	private void createTabs(Composite parent) {
		TabFolder cTabFolder = new TabFolder(parent, SWT.TOP);
		cTabFolder.setSize(parent.getClientArea().width, parent.getClientArea().height);
		for (int i = 0; i < 20; ++i) {
			TabItem cTabItem = new TabItem(cTabFolder, SWT.NONE);
			cTabItem.setText("PI " + i);

			// TODO MH: rework
			Composite tabItemComposite = new Composite(cTabFolder, SWT.NONE);
			tabItemComposite.setLayout(new FillLayout());
			cTabItem.setControl(tabItemComposite);

			Table table = new Table(tabItemComposite, SWT.HIDE_SELECTION);

			for (int j = 0; j <= 20; ++j) {
				TableColumn tableColumn = new TableColumn(table, SWT.LEFT);
				if (j > 0) {
					tableColumn.setText("P" + j);
				}
			}

			for (int k = 1; k <= 20; ++k) {
				TableItem tableItem = new TableItem(table, SWT.NONE);

				String[] rowContent = new String[20];
				for (int z = 0; z < 20; ++z) {
					if (z > 0) {
						rowContent[z] = "";
					} else {
						rowContent[z] = "R" + k;
					}
				}

				tableItem.setText(rowContent);
			}

			for (TableColumn column : table.getColumns()) {
				column.pack();
			}

			table.setHeaderVisible(true);
			table.setLinesVisible(true);
			table.layout();
		}
	}
}
